harrypotterfandomcom_zh-20200215-history
模块:Utility
This module includes useful functions --p.getArgs(myFrame) local p = {} --Frame functions function p.getFrame(bParent) local oFrame = mw.getCurrentFrame() if bParent and oFrame~=nil and oFrame:getParent() then oFrame = mw.getCurrentFrame():getParent() end return oFrame end -- Put all arguments into a real table - Returns Parent, child args table function p.getArgs(frame) local tParent = frame:getParent() local tChild = p.fetchArgs(frame.args) if frame and tParent then tParent = p.fetchArgs(tParent.args) end return tParent or tChild end function p.fetchArgs(tTmp) if not(tTmp) then return end local sName for sName ,_ in pairs( tTmp ) do if sName then return tTmp end end end --Check if args are enough for script to run function p.checkArgs(frame, iArgs,bParent) local iCount =0 local tParent, tChild = p.getArgs(frame) local tArgTable = tParent if not(bParent) then tArgTable = tChild end if not(tArgTable) then return end local value for _, value in pairs( tArgTable ) do iCount = iCount + 1 if (iCount) tonumber(iArgs) then return true end end return false end -- End Frame functions --Date functions --Check if date is in appropriate format function p.checkDate(date,format) local pat=format or "(%d%d%d%d)-(%d%d)-(%d%d)" if date then local year,month,day=date:match(pat) if year and month and day then if (tonumber(month) < 13 and tonumber(day) < 32 and not(tonumber(year)< 0)) then return true end end end return false end -- Calculate difference between two dates function p.datediff( date1, date2,bAllowNeg) if p.checkDate(date1) and p.checkDate(date2) then local tDate1 =p.getdate(date1) local tDate2 =p.getdate(date2) local days = ((os.difftime(tDate1,tDate2))/3600/24) if not(bAllowNeg) then days = math.abs(days) end return days end return 0 end --Get timestamp using custom format function p.getTimestamp(date,format) if not(p.checkDate(date,format)) then return end local pat=format or "(%d%d%d%d)-(%d%d)-(%d%d)" local year,month,day=date:match(pat) local date1=(os.time({month=month,year=year,day=day}) ) return date1 end function p.getdate(date, format) return p.getTimestamp (date, format) end function p.addDays(sDate,iDays,bReturnTable, sFormat) if (iDays and tonumber(iDays)) then iDayToSecs = iDays * 24 * 60 *60 if (bReturnTable) then return os.date("*t",p.getdate(sDate,sFormat) + iDayToSecs) end return os.date("%Y-%m-%d",p.getdate(sDate,sFormat) + iDayToSecs) end return sDate end --Get time using Iso format ((YYYY-MM-DD) function p.getfrmdate(frame) local currTable = p.getArgs(frame) if (not (currTable)) then return end date = currTable1 format = currTable2 if not(format) then format = "%Y-%m-%d" end local date1 = p.getdate(date,format) local sDate = os.date(format,date1) return sDate end local function isLeapYear (year) if ((year % 4 0) and (year % 100 ~= 0)) or (year % 400 0) then return true end end function p.isValidDate(year,month,day) local tValidDays = {31,28,31,30,31,30,31,30,31,30,31,30} local tValidMonths = {january=1,february=2,march=3,april=4, may=5,june=6,july=7,august=8,september=9,october=10,november=11,december=12} local bYear,bMonth,bDay month = tonumber(month) or string.lower(month) month = tonumber(month) or tValidMonthsmonth mw.log(year) if tonumber(year) and tonumber(year)>-1 then if isLeapYear(year) then tValidDays2=29 end bYear = true end if tValidMonthsmonth or tValidDaysmonth then bMonth =true if tonumber(month) and tonumber(day) and 0=tonumber(day) then bDay = true end end return bYear, bMonth, bDay end -- end date functions -- Table functions -- Check if table is empty function p.isEmpty(table) if next(table) nil then return true end return false end --Source: http://help.interfaceware.com/kb/112 --Saves table function p.savetable(Table) local savedTables = {} -- used to record tables that have been saved, so that we do not go into an infinite recursion local outFuncs = { 'string' = function(value) return string.format("%q",value) end; 'boolean' = function(value) if (value) then return 'true' else return 'false' end end; 'number' = function(value) return value end; } local outFuncsMeta = { __index = function(t,k) error('Invalid Type For SaveTable: '..k) end } setmetatable(outFuncs,outFuncsMeta) local tableOut = function(value) if (savedTablesvalue) then error('There is a cyclical reference (table value referencing another table value) in this set.'); end local outValue = function(value) return outFuncstype(value)(value) end local out = '{' for i,v in pairs(value) do out = out..''..outValue(i)..'='..outValue(v)..';' end savedTablesvalue = true; --record that it has already been saved return out..'}' end outFuncs'table' = tableOut; return tableOut(Table); end -- Only loads level 1 tables function p.loadtable(sTab) local tTable = {} if not(sTab) then return t end for sKey, value in string.gfind(sTab, "(^&=+)=(^&=+);") do local _,s,tKey = string.find(sKey,"%(.*)%") tKey = tonumber(tKey) or tKey tTabletKey = value end return tTable end -- prints a table with indents function p.table_print (tt, indent, done) done = done or {} indent = indent or 0 if type(tt) "table" then local sb = {} for key, value in pairs (tt) do table.insert(sb, string.rep (" ", indent)) -- indent it if type (value) "table" and not done value then done value = true table.insert(sb, '\n"'..key..'"'.."={\n"); table.insert(sb, p.table_print (value, indent + 2, done)) table.insert(sb, string.rep (" ", indent)) -- indent it table.insert(sb, "},\n"); elseif "number" type(key) then table.insert(sb, string.format("\"%s\"\n", tostring(value))) else table.insert(sb, string.format( "%s = \"%s\"\n", tostring ('"'..key..'"'), tostring(value))..",") end end mw.log(table.concat(sb)) return table.concat(sb) else return tt end end --Sorts an array function p.spairs(t, order) -- collect the keys local keys = {} local iItemCount= 0; for k in pairs(t) do keys#keys+1 = k; iItemCount = iItemCount + 1 end -- if order function given, sort by it by passing the table and keys a, b, -- otherwise just sort the keys if order then table.sort(keys, function(a,b) return order(t, a, b) end) else table.sort(keys) end -- return the iterator function local i = 0 return function() i = i + 1 if keysi then return keysi, t[keysi] end end, iItemCount end -- End table functions -- Math functions --Increments a number using iNoToIncrement function p.incNo(iNumber, iNoToIncrement) if not(tonumber(iNoToIncrement)) then iNoToIncrement = 1; end if ( tonumber(iNumber)) then iNoToIncrement = iNoToIncrement iNumber = iNumber + iNoToIncrement; return iNumber end end -- round a number function p.round(num, idp) return tonumber(string.format("%." .. (idp or 0) .. "f", num)) end --End math functions --Debugging functions -- Generates a traceback (lines where error originated) for a function in case of error function p.testFunction(fFunction) local success, result = xpcall(fFunction, function(err) return debug.traceback(err) end) return success, result end --end debug functions function p.log(oData) local sOutput = oData if type(oData) "table" then sOutput = "table ={\n" .. p.table_print(oData,4) .. "}" end mw.log(sOutput) return sOutput end function p.preprocess(text) if mw.getCurrentFrame() then return mw.getCurrentFrame():preprocess(text) end return text end return p